import logging

from flask import abort
from flask import g
from flask import render_template, jsonify
from flask import request
from flask import session

from info import db
from info.models import News, User, Comment, CommentLike
from info.modules.news import news_blue
from utils.commons import user_login_data
from utils.response_code import RET


#展示新闻详情页
@news_blue.route("/<int:new_id>")
@user_login_data
def news_detail(new_id):

    #查询新闻对象
    try:
        news=News.query.filter(News.id==new_id).first()
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR, errmsg="获取新闻失败")

    #如果新闻对象不存在，返回404
    if not news:
        abort(404)


    # 假设用户未收藏该新闻
    is_collected = False

    # 当前用户登陆了, 并且当前新闻在用户的收藏列表中:
    if g.user and news in g.user.collection_news:
        is_collected = True

    #查询该新闻评论
    try:
        comments = Comment.query.filter(Comment.news_id == new_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR,errmsg="获取评论失败")

    #查询该用户的点过的赞的对象
    comment_likes=[]
    try:
        if g.user:
            comment_likes= CommentLike.query.filter(CommentLike.user_id==g.user.id).all()
    except Exception as e:
        logging.error(e)

    #得到一个该用户点过的赞的评论列表
    comment_like_ids=[]
    for comment_like  in comment_likes:
        comment_like_ids.append(comment_like.comment_id)

    #将评论对象里面的数据转为字典
    comment_list=[]
    for comment in comments:
        comm_dict=comment.to_dict()

        #先假设该用户没有为该评论点赞
        comm_dict['is_like']=False

        #如果用户登陆且  该评论id在该用户点赞过的评论id里面
        if g.user and (comm_dict['id'] in comment_like_ids):
            comm_dict['is_like'] = True

        #将最终数据添加到列表里
        comment_list.append(comm_dict)

    #获取新闻对象数据
    data={
        "news_info":news.to_dict(),   #新闻对象数据
        "user_info":g.user.to_dict() if g.user else "" , #用户对象数据
        "is_collected":is_collected ,   #控制收藏按钮的显示与取消
        "comments":comment_list  #评论数据
    }

    return render_template('news/detail.html',data=data)


#添加收藏业务
@news_blue.route("/news_collect",methods=['post'])
@user_login_data
def news_collect():
    #判断用户是否登录
    if not g.user:
        return jsonify(errno=RET.PARAMERR,errmsg="用户未登录")

    #得到新闻id跟操作
    news_id=request.json.get("news_id")
    action=request.json.get("action")

    #得到用户对象
    try:
        news = News.query.get(news_id)
    except Exception as e:
        logging.error(e)
        return  jsonify(errno=RET.DBERR,errmsg="查询失败")

    #判断用户是否存在
    if not news:
        return jsonify(errno=RET.NODATA,errmsg="新闻不存在")

    #判断操作类型是否规范
    if not action in ['collect','cancel_collect']:
        return jsonify(errno=RET.DATAERR,errmsg="操作类型错误")

    #操作收藏与取消收藏
    if action=="collect":
        if not news in g.user.collection_news:
            g.user.collection_news.append(news)
    else:
        if  news in g.user.collection_news:
            g.user.collection_news.remove(news)

    return jsonify(errno=RET.OK,errmsg="操作成功")


#添加评论业务
@news_blue.route("/news_comment",methods=['post'])
@user_login_data
def news_comment():

    #判断用户是否登陆
    if not g.user:
        return jsonify(errno=RET.PARAMERR,errmsg="用户未登陆")

    #获取新闻id，评论内容，父评论内容
    news_id = request.json.get("news_id")
    content = request.json.get("comment")
    parent_id = request.json.get("parent_id")

    #判空
    if not all([news_id,content]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数不全")

    #查询新闻对象
    try:
        news=News.query.get(news_id)
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR,errmsg="新闻查询失败")

    #判断新闻对象是否为空
    if not news:
        return jsonify(errno=RET.NODATA,errmsg="新闻不存在")

    #创建评论对象
    comment = Comment()
    comment.user_id=g.user.id
    comment.news_id=news_id
    comment.content=content

    #看是否有父评论
    if  parent_id:
        comment.parent_id=parent_id

    #数据写入数据库
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DATAERR,errmsg="评论失败")

    return jsonify(errno=RET.OK,errmsg="评论成功",data=comment.to_dict())

#评论点赞业务
@news_blue.route("/comment_like",methods=['Post'])
@user_login_data
def comment_like():

    #判断用户是否登陆
    if not g.user:
        return jsonify(errno=RET.PARAMERR,errmsg="用户未登陆")

    comment_id = request.json.get("comment_id")
    action =request.json.get("action")

    #判断评论id跟操作类型是否为空
    if not  all([comment_id,action]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数不全")

    #判断操作类型是否规范
    if not  action in ["add","remove"]:
        return jsonify(errno=RET.DATAERR,errmsg="操作类型错误")

    #查询评论对象
    try:
        comment=Comment.query.get(comment_id)
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR,errmsg="查询评论有误")

    #判断评论对象是否存在
    if not comment:
        return jsonify(errno=RET.NODATA,errmsg="评论不存在")

    try:
        #操作数据库，如果是添加点赞
        if action=="add":
            #先查询该点赞对象在不在
            comment_like = CommentLike.query.filter(CommentLike.user_id == g.user.id, CommentLike.comment_id == comment_id).first()
            #如果不在，则创建点赞对象,并提交数据库
            if  not  comment_like:
                comment_like=CommentLike()
                comment_like.user_id=g.user.id
                comment_like.comment_id = comment_id

                db.session.add(comment_like)

                #该评论的所有点赞数加1
                comment.like_count+=1

                db.session.commit()
        #如果是删除点赞对象
        else:
            # 先查询该点赞对象在不在
            comment_like = CommentLike.query.filter(CommentLike.user_id == g.user.id, CommentLike.comment_id == comment_id).first()
            #如果点赞对象存在，则删除数据库
            if comment_like:
                db.session.delete(comment_like)
                #该评论对象的总赞数减一
                if comment.like_count>0:
                    comment.like_count-=1

                db.session.commit()

    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR,errmsg="操作失败")

    return jsonify(errno=RET.OK,errmsg="点赞成功")